iT邦幫忙

2021 iThome 鐵人賽

DAY 22
0
Modern Web

前端日常,每天 React 一下系列 第 22

【Day 21】Hook 04:useContext

  • 分享至 

  • xImage
  •  

useContext

useContext 本質上是 Context 的語法糖,
精簡了 Context 取得值的方式。


使用方法

useContext 會接收一個
「Context Object」作為參數
也就是 React.createContext() 的回傳值,
並回傳該 Context 目前的值。

// ThemeContext.js
const ThemeContext = React.createContext();

// MyComponent.js
const value = useContext(ThemeContext);

Context 目前的值則取決於上層 component
距離最近<ThemeContext.Provider>value prop。

const App = () => {
    const [dark, setDark] = useState(true);
    
    return (
        <>
            <ThemeContext.Provider value={dark}>
              <MyComponent />
            </ThemeContext.Provider>
        </>
    );
}

當 component 上層最近的
<ThemeContext.Provider> 更新時,
useContext 會觸發重新 render,
並取得最新傳遞到 ThemeContext 裡的 value

// MyComponent.js
import { ThemeContext } from './App.js';

const ButtonGroupComponent = () => {
  const darkTheme = useContext(ThemeContext)
  
  const themeStyle = {
    backgroundColor: darkTheme ? '#2c3e50': '#f1c40f',
    color: darkTheme ? '#ecf0f1' : '#2c3e50'
  }
  
  return (
    <button style={themeStyle}>useContext</button>
  );
} 

useContext(ThemeContext) 等同於 class 中的 static contextType = ThemeContext<ThemeContext.Consumer>


完整使用範例


const themes = {
  light: {
    foreground: "#000000",
    background: "#eeeeee"
  },
  dark: {
    foreground: "#ffffff",
    background: "#222222"
  }
};

const ThemeContext = React.createContext(themes.light);

function App() {
  return (
    <ThemeContext.Provider value={themes.dark}>
      <Toolbar />
    </ThemeContext.Provider>
  );
}

function Toolbar(props) {
  return (
    <div>
      <ThemedButton />
    </div>
  );
}

function ThemedButton() {
  const theme = useContext(ThemeContext);
  return (
    <button style={{ background: theme.background, color: theme.foreground }}>
      I am styled by theme context!
    </button>
  );
}

總結

useContext 只能讓你讀取 context 及訂閱其變更,
component tree 的上層仍然需要
使用 <ThemeContext.Provider> 來提供 context 的值。

但 useContext 可以讓你免去使用 Consumer
包覆要接受資料的子元件,
而是將 ThemeContext 裡面的資料直接賦予給變數,
在存取時更加直觀方便。


參考資料


上一篇
【Day 20】全局儲存庫 Context
下一篇
【Day 22】Hook 05:useReducer
系列文
前端日常,每天 React 一下30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言